{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 线性方程组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from manim import *\n",
    "\n",
    "COLORS = [BLUE, GREEN, RED, YELLOW]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from mpl_toolkits.mplot3d import Axes3D"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2 x 2 例子"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$\\begin{cases}2x&-y&=0\\\\-x&+2y&=3\\end{cases}$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "计算："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "A = np.array([[2, -1], [-1, 2]])\n",
    "b = np.array([[0], [3]])\n",
    "\n",
    "x = np.linalg.solve(A, b)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2*2矩阵形式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%manim -qm MatrixForm\n",
    "\n",
    "class MatrixForm(Scene):\n",
    "    def construct(self):\n",
    "        COLORS = [BLUE, GREEN, RED]\n",
    "        eq = MathTex(r\"\\begin{cases} +2x - 1y &= 0 \\\\ -1x + 2y &= 3 \\end{cases}\").shift(UP)\n",
    "        for i in [1, 2, 4, 5, 9, 10, 12, 13]:\n",
    "            eq[0][i].set_color(COLORS[0])\n",
    "        for i in [3, 6, 11, 14]:\n",
    "            eq[0][i].set_color(COLORS[1])\n",
    "        for i in [8, 16]:\n",
    "            eq[0][i].set_color(COLORS[2])\n",
    "\n",
    "        A = Matrix([[2, -1], [-1, 2]]).set_color(COLORS[0])\n",
    "        x = Matrix([['x'], ['y']]).set_color(COLORS[1])\n",
    "        b = Matrix([[0], [3]]).set_color(COLORS[2])\n",
    "        matrix = VGroup(A, x, MathTex(\"=\"), b).arrange(RIGHT).shift(DOWN)\n",
    "\n",
    "        label_A = MathTex(\"A\").set_color(COLORS[0]).next_to(A, DOWN)\n",
    "        label_x = MathTex(\"x\").set_color(COLORS[1]).next_to(x, DOWN).shift(DOWN*0.2)\n",
    "        label_b = MathTex(\"b\").set_color(COLORS[2]).next_to(b, DOWN)\n",
    "        label_eq = MathTex(\"=\").next_to(matrix[2], DOWN).shift(DOWN*0.9)\n",
    "        label = VGroup(label_A, label_x, label_eq, label_b)\n",
    "\n",
    "        self.add(eq, matrix, label)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2 x 2行图像"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = np.linspace(-5, 5, 100)\n",
    "y1 = 2 * x\n",
    "y2 = 1/2 * x + 3/2\n",
    "\n",
    "fig, ax = plt.subplots(figsize = (12, 7))\n",
    "ax.scatter(1, 2, s = 200, zorder=5, color = 'r', alpha = .8) \n",
    "\n",
    "ax.plot(x, y1, lw =3, label = '$2x-y=0$')\n",
    "ax.plot(x, y2, lw =3, label = '$-x+2y=3$')\n",
    "ax.plot([1, 1], [-5, 5], ls = '--', color = 'b', alpha = .5)\n",
    "ax.plot([-5, 5], [2, 2], ls = '--', color = 'b', alpha = .5)\n",
    "ax.set_xlim([-5, 5])\n",
    "ax.set_ylim([-5, 5])\n",
    "\n",
    "ax.legend()\n",
    "s = '$(1,2)$'\n",
    "ax.text(1, 2, s, fontsize = 20)\n",
    "ax.grid()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%manim -ql Row2Picture\n",
    "\n",
    "class Row2Picture(Scene):\n",
    "    def construct(self):\n",
    "        plane = Axes()\n",
    "        \n",
    "        row1 = plane.plot(lambda x: 2 * x).set_color(COLORS[0])\n",
    "        row2 = plane.plot(lambda x: 1/2 * x + 3/2).set_color(COLORS[1])\n",
    "\n",
    "        dot = Dot(plane.coords_to_point(1, 2), color=PURE_RED)\n",
    "        lines = plane.get_lines_to_point(plane.c2p(1,2))\n",
    "\n",
    "        A = Matrix([['+2', '-1'], ['-1', '+2']]).set_row_colors(COLORS[0], COLORS[1])\n",
    "        A.add(SurroundingRectangle(A.get_rows()[0]))\n",
    "        A.add(SurroundingRectangle(A.get_rows()[1]))\n",
    "        x = Matrix([['x'], ['y']])\n",
    "        b = Matrix([[0], [3]]).set_row_colors(COLORS[0], COLORS[1])\n",
    "        matrix = VGroup(A, x, MathTex(\"=\"), b).arrange(RIGHT).to_edge(UL)\n",
    "        matrix.add_background_rectangle()\n",
    "\n",
    "        dot_label = MathTex(r\"(1, 2)\", color=PURE_RED).next_to(dot, RIGHT)\n",
    "        row1_label = MathTex(r\"y=2x\", color=COLORS[0]).shift(RIGHT + DOWN*0.5)\n",
    "        row2_label = MathTex(r\"y={1\\over2}x+{3\\over2}\", color=COLORS[1]).shift(LEFT*3 + DOWN)\n",
    "        label = VGroup(row1_label, row2_label, dot_label)\n",
    "\n",
    "        self.add(plane, row1, row2, dot, lines, label)\n",
    "        self.add(matrix)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2 x 2列图像"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots()\n",
    "\n",
    "# 起始点为(0, 0)，向量[2, -1]\n",
    "col1 = ax.quiver(0, 0, 2, -1, angles='xy', scale_units='xy', scale=1, color='b')\n",
    "# 起始点为(0, 0)，向量[-1, 2]\n",
    "col2 = ax.quiver(0, 0, -1, 2, angles='xy', scale_units='xy', scale=1, color='g')\n",
    "\n",
    "# 起始点为(-1, 2)，2倍向量[-1, 2]\n",
    "new_col1 = ax.quiver(2, -1, -1, 2, angles='xy', scale_units='xy', color='g', linestyle='-.', scale=0.5, linewidth=2, edgecolor='g', fc='none')\n",
    "\n",
    "# 结果：起始点为(0, 0)，向量[0, 3]\n",
    "result = ax.quiver(0, 0, 0, 3, angles='xy', scale_units='xy', color='red', scale=1)\n",
    "\n",
    "ax.set_xlim([-4, 4])\n",
    "ax.set_ylim([-4, 4])\n",
    "\n",
    "plt.grid()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%manim -i Col2Picture\n",
    "\n",
    "class Col2Picture(Scene):\n",
    "    def construct(self):\n",
    "        plane = NumberPlane()\n",
    "        col_1 = Vector([2, -1], color=BLUE)\n",
    "        col_2 = Vector([-1, 2], color=GREEN)\n",
    "        col_3 = Vector([0, 3], color=RED)\n",
    "        col_4 = Arrow(col_1.get_end(), col_3.get_end(), buff=0, color=GREEN)\n",
    "        # col_4 = DashedVMobject(col_4)\n",
    "        col = VGroup(col_1, col_2, col_3)\n",
    "\n",
    "        matrix_tex = (\n",
    "            MathTex(\"x\\\\begin{bmatrix} +2 \\\\\\ -1 \\\\end{bmatrix}\", \"+\", \"y\\\\begin{bmatrix} -1 \\\\\\ +2 \\\\end{bmatrix} \", \"=\", \"\\\\begin{bmatrix} 0 \\\\\\ 3 \\\\end{bmatrix}\").to_edge(UL)\n",
    "            .to_edge(UL)\n",
    "            # .add_background_rectangle(color=BLACK, opacity=0.2)\n",
    "        )\n",
    "        matrix_tex[0].set_color(COLORS[0])\n",
    "        matrix_tex[2].set_color(COLORS[1])\n",
    "        matrix_tex[-1].set_color(COLORS[2])\n",
    "\n",
    "        # box = SurroundingRectangle(matrix_tex, fill_color=[BLACK])\n",
    "        matrix_tex.add_background_rectangle(color=GRAY, opacity=0.2)\n",
    "\n",
    "        label_1 = col_1.coordinate_label(color=COLORS[0])\n",
    "        label_2 = col_2.coordinate_label(color=COLORS[1])\n",
    "        label_2.shift(DOWN)\n",
    "        label_3 = col_3.coordinate_label(color=COLORS[2])\n",
    "        label_4 = MathTex(r\"2 \\begin{bmatrix}-1\\\\2\\end{bmatrix}\", color=GREEN).shift(UP + RIGHT*2)\n",
    "        label = VGroup(label_1, label_2, label_3)\n",
    "\n",
    "        self.add(matrix_tex)\n",
    "        # self.add(matrix_tex)\n",
    "        self.add(plane, col, label)\n",
    "        self.play(Transform(col_2.copy(), col_4), FadeIn(label_4), run_time=2)\n",
    "        self.wait()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3 x 3 例子"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$\\begin{cases}2x&-1y&+0z&=&0\\\\-1x&+2y&-1z&=&-1\\\\0x&-3y&+4z&=&4\\end{cases}$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3*3 矩阵形式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%manim -qh Matrix3by3\n",
    "\n",
    "class Matrix3by3(Scene):\n",
    "    def construct(self):\n",
    "        # COLORS = [BLUE, GREEN, RED]\n",
    "        eq = MathTex(r\"\\begin{cases}+2&x-1y+0z=0\\\\-1&x+2y-1z=-1\\\\0&x-3y+4z=4\\end{cases}\").shift(UP*1.5)\n",
    "        for i in [5, 6, 8, 9, 11, 12, 16, 17, 19, 20, 22, 23, 28, 30, 31, 33, 34]:\n",
    "            eq[0][i].set_color(COLORS[0])\n",
    "        for i in [7, 10, 13, 18, 21, 24, 29, 32, 35]:\n",
    "            eq[0][i].set_color(COLORS[1])\n",
    "        for i in [15, 26, 27, -1]:\n",
    "            eq[0][i].set_color(COLORS[2])\n",
    "\n",
    "        A = Matrix([[2, -1, 0], [-1, 2, -1], [0, -3, 4]]).set_color(COLORS[0])\n",
    "        x = Matrix([['x'], ['y'], ['z']]).set_color(COLORS[1])\n",
    "        b = Matrix([[0], [-1], [4]]).set_color(COLORS[2])\n",
    "        matrix = VGroup(A, x, MathTex(\"=\"), b).arrange(RIGHT).shift(DOWN)\n",
    "\n",
    "        label_A = MathTex(\"A\").set_color(COLORS[0]).next_to(A, DOWN)\n",
    "        label_x = MathTex(\"x\").set_color(COLORS[1]).next_to(x, DOWN).shift(DOWN*0.2)\n",
    "        label_b = MathTex(\"b\").set_color(COLORS[2]).next_to(b, DOWN)\n",
    "        label_eq = MathTex(\"=\").next_to(matrix[2], DOWN).shift(DOWN*1.3)\n",
    "        label = VGroup(label_A, label_x, label_eq, label_b)\n",
    "\n",
    "        self.add(eq, matrix, label)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "同样借助计算机来计算方程组："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "A = np.array([[2, -1, 0], [-1, 2, -1], [0, -3, 4]])\n",
    "b = np.array([[0], [-1], [4]])\n",
    "\n",
    "x = np.linalg.solve(A, b)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3 x 3行图像"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x1 = np.linspace(0, 10, 20)\n",
    "x2 = np.linspace(0, 10, 20)\n",
    "X1, X2 = np.meshgrid(x1, x2)\n",
    "\n",
    "fig = plt.figure(figsize = (9, 9))\n",
    "ax = fig.add_subplot(111, projection = '3d')\n",
    "\n",
    "# X3 = 2*X2 - X1\n",
    "# https://www.cnblogs.com/shanger/p/13201139.html\n",
    "ax.plot_surface(X1, 2*X1, X2, cmap ='viridis', alpha = 1)\n",
    "\n",
    "X3 = - X1 + 2 * X2 + 1\n",
    "ax.plot_surface(X1, X2, X3, cmap ='summer', alpha = 1)\n",
    "\n",
    "X3 = 0 * X1 + 3/2 * X2 + 1\n",
    "ax.plot_surface(X1, X2, X3, cmap ='spring', alpha = 1)\n",
    "\n",
    "# ax.scatter(29, 16, 3, s = 200, color = 'black')\n",
    "ax.scatter(1, 2, 0, s = 200, color = 'black')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%manim -ql Row3Picture\n",
    "\n",
    "class Row3Picture(ThreeDScene):\n",
    "    def construct(self):\n",
    "        axes = ThreeDAxes(x_range=(- 6 , 6, 1), y_range=(- 5, 5, 1), z_range=(- 6, 6, 1))\n",
    "\n",
    "        row1 = Surface(\n",
    "            lambda u, v: axes.c2p(u, 2*u, v),\n",
    "            u_range=[-2, 2], v_range=[-2, 2],\n",
    "            stroke_color=COLORS[0], fill_opacity=0.5\n",
    "        )\n",
    "        row1.set_fill_by_value(axes=axes, colorscale=[(COLORS[0], 1)], axis=2)\n",
    "\n",
    "        row2 = Surface(\n",
    "            lambda u, v: axes.c2p(u, v, -u+2*v+1),\n",
    "            u_range=[-2, 2], v_range=[-2, 2],\n",
    "            stroke_color=COLORS[1], fill_opacity=0.5\n",
    "        )\n",
    "        row2.set_fill_by_value(axes=axes, colorscale=[(COLORS[1], 1)], axis=2)\n",
    "        \n",
    "        row3 = Surface(\n",
    "            lambda u, v: axes.c2p(u, v, 3/4*v+1),\n",
    "            u_range=[-2, 2], v_range=[-2, 2],\n",
    "            stroke_color=COLORS[2], fill_opacity=0.5\n",
    "        )\n",
    "        row3.set_fill_by_value(axes=axes, colorscale=[(COLORS[2], 1)], axis=2)\n",
    "\n",
    "        dot = Dot3D(point=axes.coords_to_point(0, 0, 1), color=PURE_RED, radius=0.1)\n",
    "        \n",
    "        A = Matrix([['+2', '-1', '0'], ['-1', '+2', '-1'], ['0', '-3', '+4']]).set_row_colors(COLORS[0], COLORS[1], COLORS[2])\n",
    "        A.add(SurroundingRectangle(A.get_rows()[0]))\n",
    "        A.add(SurroundingRectangle(A.get_rows()[1]))\n",
    "        A.add(SurroundingRectangle(A.get_rows()[2]))\n",
    "        x = Matrix([['x'], ['y'], ['z']])\n",
    "        b = Matrix([[0], [-1], [+4]]).set_row_colors(COLORS[0], COLORS[1], COLORS[2])\n",
    "\n",
    "        matrix = VGroup(A, x, MathTex(\"=\"), b).arrange(RIGHT)\n",
    "        matrix.scale(0.7)\n",
    "\n",
    "        self.add_fixed_in_frame_mobjects(matrix)\n",
    "        matrix.to_corner(UL)\n",
    "        self.add(axes, row1, row2, row3, dot)\n",
    "        \n",
    "        self.set_camera_orientation(phi=60*DEGREES, theta=40*DEGREES)\n",
    "        self.move_camera(theta=(40+360)*DEGREES, run_time=8, rate_func=rate_functions.ease_in_out_sine)\n",
    "        self.wait(0.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%manim -ql Test\n",
    "\n",
    "class Test(ThreeDScene):\n",
    "    def construct(self):\n",
    "        axes = ThreeDAxes(x_range=(- 6 , 6, 1), y_range=(- 5, 5, 1), z_range=(- 6, 6, 1))\n",
    "        self.add(axes)\n",
    "        self.set_camera_orientation(phi=60*DEGREES, theta=40*DEGREES)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3 x 3列图像"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "用matplotlib在三维空间绘制向量： https://www.kuxai.com/post/94"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure(figsize = (9, 9))\n",
    "ax = fig.add_subplot(111, projection = '3d')\n",
    "\n",
    "col1 = ax.quiver(0, 0, 0, 2, -1, 0, arrow_length_ratio=0.3, color='r')\n",
    "col2 = ax.quiver(0, 0, 0, -1, 2, -3, arrow_length_ratio=0.3, color='b')\n",
    "col3 = ax.quiver(0, 0, 0, 0, -1, 4, arrow_length_ratio=0.3, color='g')\n",
    "\n",
    "ax.set_xlim(-1, 3)\n",
    "ax.set_ylim(-2, 3)\n",
    "ax.set_zlim(-4, 5)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%manim -ql ColumnPicture\n",
    "\n",
    "class ColumnPicture(ThreeDScene):\n",
    "    def construct(self):\n",
    "        axes = ThreeDAxes()\n",
    "\n",
    "        lab_x = Tex(\"$x$\").shift(DOWN*1.2 + LEFT*4)\n",
    "        lab_y = Tex(\"$y$\").shift(DOWN + RIGHT*4)\n",
    "        lab_z = Tex(\"$z$\").shift(UP*3 + RIGHT*0.4)\n",
    "        self.add_fixed_in_frame_mobjects(lab_x, lab_y, lab_z)\n",
    "\n",
    "        col1 = Vector(axes.c2p(2, -1, 0), color=COLORS[0])\n",
    "        col2 = Vector(axes.c2p(-1, 2, -3), color=COLORS[1])\n",
    "        col3 = Vector(axes.c2p(0, -1, 4), color=COLORS[2])\n",
    "\n",
    "        lines = axes.get_lines_to_point(axes.c2p(0, -1, 4))\n",
    "        self.add(lines)\n",
    "\n",
    "        label1 = MathTex(r'\\begin{bmatrix}2\\\\-1\\\\0\\end{bmatrix}', color=COLORS[0])\n",
    "        label2 = MathTex(r'\\begin{bmatrix}-1\\\\2\\\\-3\\end{bmatrix}', color=COLORS[1])\n",
    "        label3 = MathTex(r'\\begin{bmatrix}0\\\\-1\\\\4\\end{bmatrix}', color=COLORS[2])\n",
    "        label1.shift(LEFT*2.6)\n",
    "        label2.shift(DOWN + RIGHT*2)\n",
    "        label3.shift(UP*2+RIGHT*0.6)\n",
    "\n",
    "        matrix_tex = MathTex(r\"x\\begin{bmatrix} +2 \\\\ -1 \\\\0 \\end{bmatrix}\", r\"+\", r\"y\\begin{bmatrix} -1 \\\\ +2 \\\\-3 \\end{bmatrix} \", r\"+\",r\"z\\begin{bmatrix} 0 \\\\ -1 \\\\ 4 \\end{bmatrix}\", r\"=\", r\"\\begin{bmatrix} 0 \\\\ -1 \\\\4 \\end{bmatrix}\")\n",
    "        matrix_tex[0].set_color(COLORS[0])\n",
    "        matrix_tex[2].set_color(COLORS[1])\n",
    "        matrix_tex[4].set_color(COLORS[2])\n",
    "        matrix_tex[-1].set_color(YELLOW)\n",
    "\n",
    "        self.add_fixed_in_frame_mobjects(matrix_tex)\n",
    "        matrix_tex.scale(0.7).to_corner(UL)\n",
    "\n",
    "        self.add(axes, col1, col2, col3)\n",
    "        self.add_fixed_in_frame_mobjects(label1, label2, label3)\n",
    "\n",
    "\n",
    "        self.set_camera_orientation(phi=80*DEGREES, theta=40*DEGREES)\n",
    "\n",
    "        self.play(\n",
    "            col3.animate.set_color(YELLOW),\n",
    "            label3.animate.set_color(YELLOW),\n",
    "            run_time=2\n",
    "        )\n",
    "        self.play(\n",
    "            col3.animate.set_color(COLORS[2]),\n",
    "            label3.animate.set_color(COLORS[2]),\n",
    "            run_time=2\n",
    "        )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 拓展：新的b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "假如$b=\\begin{bmatrix}1\\\\1\\\\-3\\end{bmatrix}$，此时$x$是多少呢？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "A = np.array([[2, -1, 0], [-1, 2, -3], [0, -3, 4]])\n",
    "b = np.array([[1], [1], [-3]])\n",
    "\n",
    "x = np.linalg.solve(A, b)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%manim -ql NewRowPic\n",
    "\n",
    "class NewRowPic(ThreeDScene):\n",
    "    def construct(self):\n",
    "        axes = ThreeDAxes(x_range=(- 6 , 6, 1), y_range=(- 5, 5, 1), z_range=(- 6, 6, 1))\n",
    "\n",
    "        row1 = Surface(\n",
    "            lambda u, v: axes.c2p(u, 2*u-1, v),\n",
    "            u_range=[-2, 2], v_range=[-2, 2],\n",
    "            stroke_color=COLORS[0], fill_opacity=0.5\n",
    "        )\n",
    "        row1.set_fill_by_value(axes=axes, colorscale=[(COLORS[0], 1)], axis=2)\n",
    "\n",
    "        row2 = Surface(\n",
    "            lambda u, v: axes.c2p(u, v, -u+2*v-1),\n",
    "            u_range=[-2, 2], v_range=[-2, 2],\n",
    "            stroke_color=COLORS[1], fill_opacity=0.5\n",
    "        )\n",
    "        row2.set_fill_by_value(axes=axes, colorscale=[(COLORS[1], 1)], axis=2)\n",
    "        \n",
    "        row3 = Surface(\n",
    "            lambda u, v: axes.c2p(u, v, 3/4*v-3/4),\n",
    "            u_range=[-2, 2], v_range=[-2, 2],\n",
    "            stroke_color=COLORS[2], fill_opacity=0.5\n",
    "        )\n",
    "        row3.set_fill_by_value(axes=axes, colorscale=[(COLORS[2], 1)], axis=2)\n",
    "\n",
    "        dot = Dot3D(point=axes.coords_to_point(1, 1, 0), color=PURE_RED, radius=0.1)\n",
    "        \n",
    "        A = Matrix([['+2', '-1', '0'], ['-1', '+2', '-1'], ['0', '-3', '+4']]).set_row_colors(COLORS[0], COLORS[1], COLORS[2])\n",
    "        A.add(SurroundingRectangle(A.get_rows()[0]))\n",
    "        A.add(SurroundingRectangle(A.get_rows()[1]))\n",
    "        A.add(SurroundingRectangle(A.get_rows()[2]))\n",
    "        x = Matrix([['x'], ['y'], ['z']])\n",
    "        b = Matrix([[1], [1], [-3]]).set_row_colors(COLORS[0], COLORS[1], COLORS[2])\n",
    "\n",
    "        matrix = VGroup(A, x, MathTex(\"=\"), b).arrange(RIGHT)\n",
    "        matrix.scale(0.7)\n",
    "\n",
    "        self.add_fixed_in_frame_mobjects(matrix)\n",
    "        matrix.to_corner(UL)\n",
    "        self.add(axes, row1, row2, row3, dot)\n",
    "        \n",
    "        self.set_camera_orientation(phi=60*DEGREES, theta=40*DEGREES)\n",
    "        self.move_camera(theta=(40+360)*DEGREES, run_time=8, rate_func=rate_functions.ease_in_out_sine)\n",
    "        self.wait(0.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%manim -i NewColPic\n",
    "\n",
    "class NewColPic(ThreeDScene):\n",
    "    def construct(self):\n",
    "        axes = ThreeDAxes()\n",
    "\n",
    "        lab_x = Tex(\"$x$\").shift(DOWN*1.2 + LEFT*4)\n",
    "        lab_y = Tex(\"$y$\").shift(DOWN + RIGHT*4)\n",
    "        lab_z = Tex(\"$z$\").shift(UP*3 + RIGHT*0.4)\n",
    "        self.add_fixed_in_frame_mobjects(lab_x, lab_y, lab_z)\n",
    "\n",
    "        col1 = Vector(axes.c2p(2, -1, 0), color=COLORS[0])\n",
    "        col2 = Vector(axes.c2p(-1, 2, -3), color=COLORS[1])\n",
    "        col3 = Vector(axes.c2p(0, -1, 4), color=COLORS[2])\n",
    "        col4 = Vector(axes.c2p(1, 1, -3), color=YELLOW)\n",
    "        col2_cp = Arrow(col1.get_end(), col4.get_end(), buff=0, color=COLORS[1])\n",
    "\n",
    "        label1 = MathTex(r'\\begin{bmatrix}2\\\\-1\\\\0\\end{bmatrix}', color=COLORS[0])\n",
    "        label2 = MathTex(r'\\begin{bmatrix}-1\\\\2\\\\-3\\end{bmatrix}', color=COLORS[1])\n",
    "        label3 = MathTex(r'\\begin{bmatrix}0\\\\-1\\\\4\\end{bmatrix}', color=COLORS[2])\n",
    "        label4 = MathTex(r'\\begin{bmatrix}1\\\\1\\\\-3\\end{bmatrix}', color=YELLOW)\n",
    "        label1.shift(LEFT*2.6)\n",
    "        label2.shift(DOWN + RIGHT*2)\n",
    "        label3.shift(UP*2+RIGHT*0.6)\n",
    "        label4.shift(DOWN*3 + RIGHT)\n",
    "\n",
    "        matrix_tex = MathTex(r\"x\\begin{bmatrix} +2 \\\\ -1 \\\\0 \\end{bmatrix}\", r\"+\", r\"y\\begin{bmatrix} -1 \\\\ +2 \\\\-3 \\end{bmatrix} \", r\"+\",r\"z\\begin{bmatrix} 0 \\\\ -1 \\\\ 4 \\end{bmatrix}\", r\"=\", r\"\\begin{bmatrix} 1 \\\\ 1 \\\\-3 \\end{bmatrix}\")\n",
    "        matrix_tex[0].set_color(COLORS[0])\n",
    "        matrix_tex[2].set_color(COLORS[1])\n",
    "        matrix_tex[4].set_color(COLORS[2])\n",
    "        matrix_tex[-1].set_color(YELLOW)\n",
    "\n",
    "        self.set_camera_orientation(phi=80*DEGREES, theta=40*DEGREES)\n",
    "\n",
    "        self.add_fixed_in_frame_mobjects(matrix_tex)\n",
    "        matrix_tex.scale(0.7).to_corner(UL)\n",
    "\n",
    "        self.add(axes, col1, col2, col3, col4)\n",
    "        self.add_fixed_in_frame_mobjects(label1, label2, label3, label4)\n",
    "\n",
    "        self.play(Transform(col2.copy(), col2_cp))\n",
    "        self.wait()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 编程实现报错\n",
    "A = np.array([[2, -1, 1], [-1, 2, 1], [1, 1, 2]])\n",
    "b = np.array([[1], [1], [-3]])\n",
    "\n",
    "x = np.linalg.solve(A, b)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 矩阵 x 向量"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 方式1: 1次1列"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$\\begin{bmatrix}2&5\\\\1&3\\end{bmatrix}\\begin{bmatrix}1\\\\2\\end{bmatrix}=1\\begin{bmatrix}2\\\\1\\end{bmatrix}+2\\begin{bmatrix}5\\\\3\\end{bmatrix}=\\begin{bmatrix}12\\\\7\\end{bmatrix}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%manim -i Col\n",
    "\n",
    "class Col(ThreeDScene):\n",
    "    def construct(self):\n",
    "        A = Matrix([[2, 5], [1, 3]]).set_column_colors(COLORS[0], COLORS[1])\n",
    "        x = Matrix([[1], [2]]).set_row_colors(COLORS[0], COLORS[1])\n",
    "        b = Matrix([[12], [7]])\n",
    "        temp = MathTex(r\"1\", r\"\\begin{bmatrix}2\\\\1\\end{bmatrix}\", r\"+\", r\"2\", r\"\\begin{bmatrix}5\\\\3\\end{bmatrix}\")\n",
    "        temp[0:2].set_color(COLORS[0])\n",
    "        temp[3:5].set_color(COLORS[1])\n",
    "\n",
    "        eq = VGroup(A, x, MathTex(\"=\"), temp, MathTex(\"=\"), b).arrange(RIGHT)\n",
    "\n",
    "        self.add(eq)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 方式2: 点乘"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\\begin{bmatrix}2 & 5 \\\\ 1 & 3\\end{bmatrix} = \n",
    "\\begin{bmatrix}1 \\times 2 + 2 \\times 5 \\\\ 1 \\times 1 + 2 \\times 3\\end{bmatrix} = \n",
    "\\begin{bmatrix} 12 \\\\ 7 \\end{bmatrix}"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.6"
  },
  "vscode": {
   "interpreter": {
    "hash": "a045e4431ffd8513cc3dbf8da28750ecc933a5bdc7eb2f9318e5ad089d534439"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
